package com.sakiko.javaConfig_03;

import com.sakiko.ioc_03.UserDao;
import com.sakiko.ioc_03.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;

@Configuration
// 没写注解，不用 componentScan
@PropertySource("classpath:jdbc.properties")
public class javaConfig {

//    @Value("${jdbc.url}")
//    private String url;

    /**
     * @return 要放入 ioc容器的组件，这里是 userDao
     * @Bean -> 返回值 -> ioc容器中！！！
     * 细节一: 组件的名称 默认: 方法名 修改方式
     * 1、改方法名
     * 2、通过 @Bean( name | value )
     * 细节二: 如何设置周期方法
     * 1、接口 InitializingBean | DisposableBean
     * 2、注解 @PostConstruct | @PreDestroy
     * 3、xml: init-method | destroy-method
     * 4、@Bean(initMethod= |destroyMethod=)
     * 细节三: 如何设置对象模式 单例 | 多例
     * 1、@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) | singleton
     * @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) | prototype
     * 细节四: 如何设置非引用类型的值
     * 1、配置类中声明变量 + @Value注解
     * 2、@Bean的形参列表中 + @Value("toXxx") Xxx xxx 【推荐】
     * 细节五: 如何设置引用类型的值
     * 1、@Bean的形参列表中 + (其他组件类型 对象名) -> 核心容器会自动按照类型注入
     * 存在 NoSuch、NoUnique的异常，6.0.6参考 spring_ioc_annotation_xml_02\src\...\ioc_03\UserService.java
     * note: spring 6.0.6 不加 @Qualifier("userDao") 也会按 id找下，如上行参考笔记位置； 但是改成 spring 6.2.7就会出现 NoUnique异常
     * note: 这是 spring 6.2的功能改动，可以看第一次提交时评论
     */
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    @Bean(name = "sakiko",
            initMethod = "begin",
            destroyMethod = "stop")
    public UserDao xxx(@Value("${jdbc.url}") String url) {
        UserDao userDao = new UserDao();
        userDao.setUrl(url);
        return userDao;
    }

    @Bean
    public UserDao userDao(@Value("${jdbc.url}") String url) {
        UserDao userDao = new UserDao();
        userDao.setUrl(url);
        return userDao;
    }

    @Bean
    public UserService userService(@Qualifier("userDao") UserDao userDao) {
        UserService userService = new UserService();
        userService.setUserDao(userDao);
        return userService;
    }
}
